package
{
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.events.TimerEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.html.*;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.Timer;
	
	import mx.containers.VBox;
	import mx.controls.Alert;
	import mx.controls.ProgressBar;
	import mx.controls.Text;
	import mx.core.Application;
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;


	public class Thread
	{

		private var params:Object={}; // holds the params to send in the request.
		private var file:File; // reserve file location
		private var response:Array; // the array which carries the respond file.
		private var _url:String; // MP3 url
		private var html:HTMLLoader; // load the result page
		private var fileLoader:URLLoader; // load the MP3 file
		private var fileName:String="Converting your file.."; // hold the MP3 Name
		private var downloadLink:Object; // hold the MP3 url link object
		private var fs:FileStream; // the Mp3 itself
		private var timer:Timer; // main timer to start download
		private var fadeTimer:Timer; // wating till fade ends.
		private var progress:Timer; // progress timer for download
		private var msgTimer:Timer; // 5 seconds timer until server is not busy
		private var waitTimer:Timer;
		private var countdown_num:Number; // vars by serviece
		private var countdown_total:Number; // vars by serviece

		private var httpService:HTTPService;
		private var msgService:HTTPService;

		public var vbox:VBox;
		public var txt:Text;
		private var progressBar:ProgressBar;

		public function Thread()
		{
			vbox=new VBox();
			vbox.styleName="progressBox";
			vbox.percentWidth=100;
			// make the progress bar
			progressBar=new ProgressBar();
			progressBar.setStyle('paddingLeft',15);
			progressBar.percentWidth=75;
			// make the info text
			txt=new Text();
			txt.setStyle('paddingTop',10);
			txt.setStyle('paddingLeft',15);
			txt.text=fileName;
			// append to vbox
			vbox.addChild(txt);
			vbox.addChild(progressBar);
			// now send the request
			sendhttpRequest();
			sendMsgRequest();
		}

		/**
		 * send httprequest
		 * */
		private function sendhttpRequest():void
		{
			httpService=new HTTPService();
			httpService.addEventListener(ResultEvent.RESULT, handleResult);
			httpService.addEventListener(FaultEvent.FAULT, handleFault);
			httpService.url="http://www.video2mp3.net/check.php";
			httpService.resultFormat="text";
			httpService.useProxy=false;
			httpService.method="POST";
			httpService.contentType="application/x-www-form-urlencoded";

			params["url"]=encodeURIComponent(Application.application.textInput.text);
			params["hq"]=Application.application.hq; // HQ or not ? 1:0
			params["server"]='';
			params["lang"]='en';
			params["adblock"]=0;

			httpService.send(params); // 2lbi ma3ik :D
		}

		/**
		 * send the second requesy Message Request.
		 * */
		private function sendMsgRequest():void
		{
			msgService=new HTTPService();
			msgService.addEventListener(ResultEvent.RESULT, handleResult);
			msgService.addEventListener(FaultEvent.FAULT, handleFault);
			msgService.resultFormat="text";
			msgService.useProxy=false;
			msgService.method="GET";
		}

		/**
		 * handle the main httprequest
		 * */
		private function handleResult(event:ResultEvent):void
		{
			response=event.result.toString().split("|");
			if (response[0] == 'WAIT')
			{
				_url=response[5]; // the main url is in response[5]
				countdown_num=Number(Number(response[1]) * 10);
				countdown_total=Number(Number(response[1]) * 10);
				
				// set converting progerss
				progressBar.minimum=0;
				progressBar.maximum=countdown_total;
				progressBar.mode="manual";

				// time out timer
				timer=new Timer(Number(response[1]) * 1000);
				timer.addEventListener(TimerEvent.TIMER, goToURL);
				timer.start();

				// progress timer
				progress=new Timer(100);
				progress.addEventListener(TimerEvent.TIMER, showProgress);
				progress.start();
			}
			else if (response[0] == 'MESSAGE')
			{
				var msgUrl:String="http://www.video2mp3.net/update.php?v=";
				msgUrl+=response[2] + "&service=" + response[3];
				msgUrl+="&hostname=" + response[5];
				msgUrl+="&lang=en";
				msgService.url=msgUrl;

				//wait 5 seconds then send .. server might be busy
				// timer here
				msgTimer=new Timer(5000);
				msgTimer.addEventListener(TimerEvent.TIMER, sendToServerAgain);
				msgTimer.start();
			}
			else if (response[0] == 'REDIRECT')
			{
				_url=response[1]; // the main url is in response[5]
				// time out timer
				timer=new Timer(100);
				timer.addEventListener(TimerEvent.TIMER, goToURL);
				timer.start();
			}
			else // fail cases
			{
				removeAllBoxes();
				Alert.show("Error !: " + event.result.toString());
			}
		}

		/**
		 * handle http request errors
		 * */
		private function handleFault(event:FaultEvent):void
		{
			removeAllBoxes();
			Alert.show("Internal Error! plz try again");
		}

		/**
		 * try to send again to server
		 * */
		private function sendToServerAgain(event:TimerEvent):void
		{
			msgTimer.stop();
			msgService.send();
		}

		/**
		 * grab the entire html page
		 * */
		private function goToURL(event:TimerEvent):void
		{
			//var webPageURL:URLRequest=new URLRequest(_url);
			//navigateToURL(webPageURL, '_blank')
			timer.stop();

			html=new HTMLLoader();
			html.addEventListener(Event.COMPLETE, checkTrafficonBrowseForSave);
			html.load(new URLRequest(_url));
		}

		/**
		 * check traffic on browseForSave
		 * */
		private function checkTrafficonBrowseForSave(event:Event):void
		{
			if (Application.application.holdForBrowes.length == 0)
			{
				Application.application.holdForBrowes.push(1); // make busy flag
				onHtmlLoadComplete(); // go ahead.
			}

			else
			{
				// check again within 4 sec.
				waitTimer=new Timer(4000);
				waitTimer.addEventListener(TimerEvent.TIMER, holdForSave);
				waitTimer.start();
			}
		}

		/**
		 * wait here until u got permission
		 * */
		private function holdForSave(event:TimerEvent):void
		{
			if (Application.application.holdForBrowes.length == 0)
			{
				checkTrafficonBrowseForSave(event);
				waitTimer.stop();
			}
		}

		/**
		 * get download link and occupy the file location.
		 * */
		private function onHtmlLoadComplete():void
		{
			// get song url
			downloadLink=html.window.document.getElementById("download");
			// get song name
			var docName:String=html.window.document.getElementsByTagName('title')[0].innerHTML;
			var tmpArray:Array=docName.split(": ");
			fileName=tmpArray[1];
			// remove " or ' from file name , sure?
			var strArray:Array=fileName.split("\"");
			fileName='';
			for each( var str:String in strArray)
				fileName+=str;
			
			txt.text=fileName;

			// choose save location
			file=File.desktopDirectory.resolvePath(fileName);
			file.addEventListener(Event.SELECT, saveAndDownloadMP3);
			file.addEventListener(Event.CANCEL, cancelBrowse);
			file.browseForSave("Save As");

		}

		/**
		 * Cancel downloading the song
		 * */
		private function cancelBrowse(event:Event):void
		{
			// let another one go for save.
			Application.application.holdForBrowes.pop();
			// remove file.
			file=null;

			// wait 1 sec for fade
			fadeTimer = new Timer(1010);
			fadeTimer.addEventListener(TimerEvent.TIMER, removeVBox);
			fadeTimer.start();
		}

		/**
		 * save the final mp3 in desired location
		 * */
		private function saveAndDownloadMP3(event:Event):void
		{
			// let another one go for save.
			Application.application.holdForBrowes.pop();

			// add .mp3 extention if not exist
			var airFile:File=event.currentTarget as File;
			if (!airFile.extension || airFile.extension != "mp3")
			{
				airFile.nativePath+=".mp3";
			}

			fs=new FileStream();
			fs.open(airFile, FileMode.WRITE);

			// download the mp3
			fileLoader=new URLLoader();
			fileLoader.addEventListener(ProgressEvent.PROGRESS, donwloadProgress);
			fileLoader.addEventListener(Event.COMPLETE, onDownloaded);
			fileLoader.dataFormat=URLLoaderDataFormat.BINARY;
			fileLoader.load(new URLRequest(downloadLink.toString()));

			//progressBar=new ProgressBar();
			progressBar.setProgress(0, countdown_total);
			progressBar.minimum=0;
			progressBar.maximum=fileLoader.bytesTotal;
			progressBar.mode="manual";
		}

		/**
		 * when downloading the mp3 is done
		 * */
		private function onDownloaded(event:Event):void
		{
			fs.writeBytes(fileLoader.data);
			fs.close();

			fadeTimer = new Timer(1010);
			fadeTimer.addEventListener(TimerEvent.TIMER, removeVBox);
			fadeTimer.start();
		}

		/**
		 * download progress bar
		 * */
		private function donwloadProgress(event:ProgressEvent):void
		{
			progressBar.setProgress(event.bytesLoaded, event.bytesTotal);
		}

		/**
		 * show progress bar
		 * */
		private function showProgress(event:TimerEvent):void
		{
			countdown_num--;
			if (countdown_num >= 0)
			{
				progressBar.setProgress(countdown_total - countdown_num, countdown_total);
					//progressText.text=(int(100 - (countdown_num / countdown_total * 100))).toString() + "%";
			}
			else
			{
				progress.stop();
			}
		}
		
		private function removeVBox(event:TimerEvent):void
		{
			fadeTimer.stop();
			removeAllBoxes();	
		}
		private function removeAllBoxes():void
		{
			vbox.removeAllChildren();
			Application.application.thisBox.removeChild(vbox);
			if (Application.application.thisBox.numChildren == 0)
				Application.application.thisBox.visible=false;
		}
	}
}